#include <iostream>
#include <thread>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <pthread.h>
#include <cstdio>

using namespace std;
// 如果多线程访问同一个全局变量，并对它进行数据计算，多线程会互相影响吗？
int tickets = 10000; // 在并发访问的时候，导致了我们数据不一致的问题！

void *getTickets(void *args)
{
    (void)args;
    while(true)
    {
        if(tickets > 0)
        {
            usleep(1000);
            printf("%p: %d\n", pthread_self(), tickets);
            tickets--;
        }
        else{
            break;
        }
    }
    return nullptr;
}

int main()
{
    pthread_t t1,t2,t3;
    // 多线程抢票的逻辑
    pthread_create(&t1, nullptr, getTickets, nullptr);
    pthread_create(&t2, nullptr, getTickets, nullptr);
    pthread_create(&t3, nullptr, getTickets, nullptr);

    pthread_join(t1, nullptr);
    pthread_join(t2, nullptr);
    pthread_join(t3, nullptr);
}


// void fun()
// {
//     while(true)
//     {
//         cout << "hello new thread" << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     std::thread t(fun);
//     std::thread t1(fun);
//     std::thread t2(fun);
//     std::thread t3(fun);
//     std::thread t4(fun);

//     while(true)
//     {
//         cout << "hello main thread" << endl;
//         sleep(1);
//     }

//     t.join();
// }

// // _ _thread : 修饰全局变量，带来的结果就是让每一个线程各自拥有一个全局的变量 -- 线程的局部存储
 //__thread int g_val = 0;

// // 1. 线程谁先运行与调度器相关`
// // 2. 线程一旦异常，都可能导致整个进程整体退出
// // 3. 线程的输入和返回值问题
// // 4. 线程异常退出的理解
// void *threadRoutine(void *args)
// {
//     //pthread_detach(pthread_self());

//     // sleep(5);
//     // execl("/bin/ls", "ls", nullptr);
//     while(true)
//     {
//         cout << (char*)args << " : " << g_val << " &: " << &g_val << endl;
//         g_val++;
//         sleep(1);
//         // int a = 10;
//         // a /= 0;
//         break;
//     }
//     pthread_exit((void*)11);
//     // pthread_cancel(pthread_self()); // 不推荐
//     // int i = 0;
//     // // int *data = new int[10];
//     // while (true)
//     // {
//     //     cout << "新线程： " << (char *)args << " running ..." << pthread_self() << endl;
//     //     sleep(1);
//     //     // data[i] = i;
//     //     // if(i++ == 3) break;
//     //     // int a  = 100;
//     //     // a /= 0;
//     // }
//     // pthread_exit((void*)13);
//     // exit(10); // 不要调用exit，exit是终止进程的！
//     // cout << "new thread quit ..." << endl;
//     // return (void*)data;
//     // return (void *)10; // 是返回给谁呢？一般是给main thread, main如何获取到呢？pthread_join
// }

// int main()
// {
    // // 因为我们目前用的不是Linux自带的创建线程的接口，我们用的是pthread库中的接口！
    // pthread_t tid; // 本质是一个地址！
    // pthread_create(&tid, nullptr, threadRoutine, (void *)"thread 1");

    // while(true)
    // {
    //     cout << "main thread" << " : " << g_val << " &: " << &g_val << endl;
    //     sleep(100);
    //     break;
    // }
    // int n = pthread_join(tid, nullptr);
    // cout << "n :" << n << "errstring: " << strerror(n) << endl;

    // // printf("%lu, %p\n", tid, tid);
    // int count = 0;
    // while (true)
    // {
    //     cout << "main线程： "
    //          << " running ... main tid: " << pthread_self() << endl;
    //     sleep(1);
    //     count++;
    //     if (count >= 5)
    //         break;
    // }
    // pthread_cancel(tid);
    // cout << "pthread cancel: " << tid << endl;

    // int *ret = nullptr;
    // pthread_join(tid, (void **)&ret); // 默认会阻塞等待新线程退出

    // 1. 线程被取消，join的时候，退出码是-1 #define PTHREAD_CANCELED ((void *) -1)
    // PTHREAD_CANCELED;
    // cout << "main thread wait done ... main quit ...: new thead quit : " << (long long)ret << "\n";
    // sleep(5);

    // for(int i = 0; i < 10; i++)
    // {
    //     cout << ret[i] << endl;
    // }
    // 3. 线程在创建并执行的时候，线程也是需要进行等待的，如果主线程如果不等待，即会引起类似于进程的僵尸问题，导致内存泄漏
    // while(true)
    // {
    //     cout <<"main线程： " << " running ..." << endl;
    //     sleep(1);
    // }
//     return 0;
// }